

package com.yungu.swift.api.route.v2.passenger;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yungu.swift.api.base.gateway.CurrentUser;
import com.yungu.swift.api.utils.RandomUtil;
import com.yungu.swift.assets.passenger.model.dto.PassengerCouponDto;
import com.yungu.swift.assets.passenger.model.dto.PassengerDto;
import com.yungu.swift.assets.passenger.model.param.ApiPasPayCouponParam;
import com.yungu.swift.assets.passenger.model.param.ApiPassengerLoginParam;
import com.yungu.swift.assets.passenger.model.param.ApiPassengerQrCodeParam;
import com.yungu.swift.assets.passenger.model.vo.PassengerVo;
import com.yungu.swift.assets.passenger.service.PassengerCouponService;
import com.yungu.swift.assets.passenger.service.PassengerService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.model.api.ApiBusinessPageParam;
import com.yungu.swift.base.model.api.ApiParam;
import com.yungu.swift.common.model.dto.CommonIdentifyDto;
import com.yungu.swift.common.service.CommonSmsService;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.constants.MagicConstant;
import com.yungu.swift.constants.PassengerConstant;
import com.yungu.swift.system.marketing.model.dto.MarketingGiftCodeDto;
import com.yungu.swift.system.marketing.model.dto.MarketingGiftDto;
import com.yungu.swift.system.marketing.service.MarketingGiftCodeService;
import com.yungu.swift.system.marketing.service.MarketingGiftService;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.ParamUtil;
import com.yungu.swift.utils.StringUtils;
import com.yungu.swift.utils.ValidateUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Pattern;

import static com.yungu.swift.api.base.ApiErrorEnum.PARAM_ERROR;
import static com.yungu.swift.assets.passenger.model.enums.PassengerErrorEnum.*;

/**
 * @author Zerrion
 * @version 1.0
 * @description
 * @date 2018/9/23 17:54
 */
@RestController
@RequestMapping("/api/v2/passenger/token/coupon")
@Api(value = "【乘客】【优惠券】乘客优惠券接口V2", tags = "V2-乘客优惠券接口")
public class PasCouponApi {

    @Reference
    private MarketingGiftService marketingGiftService;
    @Reference
    private PassengerService passengerService;
    @Reference
    private PassengerCouponService passengerCouponService;
    @Reference
    private CommonSmsService commonSmsService;
    @Reference
    private MarketingGiftCodeService marketingGiftCodeService;


    @PostMapping(value = "/drawQrCodeGift")
    @ApiOperation(value = "领取二维码礼包接口")
    public ResponseData<Map<String, Object>> drawQrCodeGift(@Valid @RequestBody ApiPassengerQrCodeParam qrCodeParam) {
        String decryptMobile = RandomUtil.randomDecrypt(qrCodeParam.getMobile());
        //判断电话是否准确
        if (!ValidateUtils.validateMobile(decryptMobile)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "请输入正确的手机号");
        }
        String decryptIdentifyCode = RandomUtil.randomDecrypt(qrCodeParam.getIdentifyCode());
        if (decryptIdentifyCode.length() != MagicConstant.INT_FOUR) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "请输入正确的验证码");
        }
        //校验验证码是否存在
        String mobileTop3 = decryptMobile.substring(0, 3);
        CommonIdentifyDto identify = null;
        if (!mobileTop3.equals(MagicConstant.STRING_ONE_FOUR_TWO)) {
            Map<String, Object> paramMap = MapUtils.build(8);
            paramMap.put("mobile", decryptMobile);
            paramMap.put("identifyCode", decryptIdentifyCode);
            paramMap.put("status", CommonConstant.IDENTIFY_CODE_STATUS_UNUSED);
            paramMap.put("appid", qrCodeParam.getAppid());
            if ((identify = commonSmsService.get(paramMap).getData()) == null) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "请输入正确的验证码");
            }
        }
        //查找是否存在用户
        Map<String, Object> map = MapUtils.build(4);
        map.put("mobile", decryptMobile);
        map.put("appid", qrCodeParam.getAppid());
        PassengerDto passengerDto = passengerService.get(map).getData();
        // 判断当前礼包状态
        MarketingGiftDto currentMarketingGift = marketingGiftService.get(MapUtils.build("uuid", qrCodeParam.getGiftUuid())).getData();
        ResponseData validateData = validateGift(currentMarketingGift, passengerDto);
        if (!validateData.isSuccess()) {
            return ResponseData.buildErrorResponse(validateData.getErrCode(), validateData.getMsg());
        }
        // 新用户注册
        if (passengerDto == null) {
            ApiPassengerLoginParam passengerLoginParam = new ApiPassengerLoginParam();
            passengerLoginParam.setMobile(decryptMobile);
            passengerLoginParam.setActive(2);
            passengerLoginParam.setGiftUuid(qrCodeParam.getGiftUuid());
            ResponseData<PassengerVo> login = passengerService.login(passengerLoginParam);
            if (login.isSuccess() && login.getData() != null && !mobileTop3.equals(MagicConstant.STRING_ONE_FOUR_TWO)) {
                //更新验证码
                final CommonIdentifyDto IdentifyDto = identify;
                IdentifyDto.setStatus(CommonConstant.IDENTIFY_CODE_STATUS_USED);
                CompletableFuture.runAsync(() -> commonSmsService.edit(IdentifyDto));
            }
        }
        return marketingGiftService.drawQrCodeGift(passengerDto.getAppid(), passengerDto.getUuid(), qrCodeParam.getGiftUuid(),
                qrCodeParam.getCid(), passengerDto == null);
    }


    @RequestMapping(value = {"/drawCdkeyGift"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value = "兑换/口令码领取礼包接口", notes = "")
    public ResponseData<Map<String, Object>> drawCdkeyGift(@RequestBody Map<String, String> codeMap, @CurrentUser ApiParam apiParam) {
        // 兑换/口令码
        String code = codeMap.get("code");
        if (ParamUtil.isIllegal(code)) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        //输入检查
        String giftCode = "[A-Za-z0-9\u4e00-\u9fa5]{1,20}";
        if (!Pattern.matches(giftCode, code)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "非法输入");
        }
        //验证兑换码有效性
        ResponseData<Boolean> verifyCode = marketingGiftCodeService.verifyCode(code);
        if (!verifyCode.isSuccess() || verifyCode.getData() == null || Objects.equals(verifyCode.getData(), Boolean.FALSE)) {
            return ResponseData.buildErrorResponse(verifyCode.getErrCode(), verifyCode.getMsg());
        }
        MarketingGiftCodeDto marketingGiftCodeDto = marketingGiftCodeService.get(MapUtils.build("code", code)).getData();
        String giftUuid = marketingGiftCodeDto.getGiftUuid();
        //查找是否存在用户
        PassengerDto passengerDto = passengerService.get(apiParam.getUserUuid()).getData();
        // 判断当前礼包状态
        MarketingGiftDto currentMarketingGift = marketingGiftService.get(giftUuid).getData();
        ResponseData validateGift = validateGift(currentMarketingGift, passengerDto);
        if (!validateGift.isSuccess()) {
            return ResponseData.buildErrorResponse(validateGift.getErrCode(), validateGift.getMsg());
        }
        //领取发放
        ResponseData<Map<String, Object>> giftData = marketingGiftService.drawQrCodeGift(apiParam.getAppid(),
                apiParam.getUserUuid(), giftUuid, null, false);
        if (giftData.isSuccess() && giftData.getData() != null) {
            // 只有兑换码类型为1的才需要设置为失效
            if (marketingGiftCodeDto.getCodeType() == 1) {
                marketingGiftCodeService.disableCode(code);
            }
        }
        return giftData;


    }

    private ResponseData<Void> validateGift(MarketingGiftDto marketingGiftDto, PassengerDto passengerDto) {
        if (marketingGiftDto == null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "活动未开始或活动已失效");
        }
        if (marketingGiftDto.getLimitDrawType() != null) {
            // 礼包为限制新用户礼包且当前用户不是新用户
            if (marketingGiftDto.getLimitDrawType() == CommonConstant.LIMIT_DRAW_TYPE_NEW_USER && passengerDto != null) {
                return ResponseData.buildErrorResponse(NEW_USER_ACTIVITY.getCode(), NEW_USER_ACTIVITY.getMsg());
            }
            // 礼包为限制老用户礼包且当前用户不是老用户
            if (marketingGiftDto.getLimitDrawType() == CommonConstant.LIMIT_DRAW_TYPE_OLD_USER && passengerDto == null) {
                return ResponseData.buildErrorResponse(OLD_USER_ACTIVITY.getCode(), OLD_USER_ACTIVITY.getMsg());
            }
        }
        // 判断活动是否开启 或者 当前时间小于活动开始时间
        if (System.currentTimeMillis() < marketingGiftDto.getEffectiveDate().getTime()) {
            return ResponseData.buildErrorResponse(ACTIVITY_NOT_OPEN.getCode(), ACTIVITY_NOT_OPEN.getMsg());

        }
        // 当前时间大于活动结束时间
        if (CommonConstant.STATUS_CLOSED.equals(marketingGiftDto.getStatus()) || marketingGiftDto.getExpiryDate().getTime() < System.currentTimeMillis()) {
            return ResponseData.buildErrorResponse(ACTIVITY_CLOSED.getCode(), "活动已结束");
        }
        // 领取数量
        if (marketingGiftDto.getRemainNumber() <= 0) {
            return ResponseData.buildErrorResponse(GIFT_QUANTITY_LACK.getCode(), GIFT_QUANTITY_LACK.getMsg());
        }
        return ResponseData.buildSuccessResponse(null);
    }

    @ApiOperation(value = "乘客获取可用的优惠券接口")
    @PostMapping(value = {"/listUsable"})
    public ResponseData<List<PassengerCouponDto>> getUseCouponList(@RequestBody ApiBusinessPageParam businessPageParam) {
        return passengerCouponService.getUseCouponList(businessPageParam);
    }

    @ApiOperation(value = "乘客支付时选择可用优惠券接口")
    @PostMapping(value = {"/listPay"})
    public ResponseData<List<PassengerCouponDto>> getPayCouponList(@RequestBody ApiPasPayCouponParam couponParam) {
        return passengerCouponService.getPayCouponList(couponParam);
    }

    @ApiOperation(value = "乘客修改优惠券状态接口")
    @PostMapping(value = {"/release"})
    public ResponseData<Boolean> release(@RequestBody Map<String, String> map, @CurrentUser ApiParam apiParam) {
        // 优惠券id
        String couponId = map.get("couponId");
        if (StringUtils.isEmpty(couponId)) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        PassengerCouponDto passengerCouponDto = new PassengerCouponDto();
        passengerCouponDto.setUuid(couponId);
        passengerCouponDto.setStatus(PassengerConstant.COUPON_STATUS_VALID);
        passengerCouponDto.setUpdateOn(new Date());
        passengerCouponDto.setUpdateBy(apiParam.getUserUuid());
        return passengerCouponService.edit(passengerCouponDto);
    }
}
